﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpTrack.Data.Model;
using SharpTrack.Data.Filters;
using SharpTrack.Data.Test.Fakes;
using SharpTrack.Application.Services;

namespace SharpTrack.Data.Test {
    /// <summary>
    /// Summary description for ProjectsRepositoryTest
    /// </summary>
    [TestClass]
    public class ProjectsRepositoryTest {


        public ProjectsRepositoryTest() {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion
     

        [TestMethod]
        public void Project_Repository_Has_10_Projects() {
            DataAccess.IProjectsRepository repository = new Fakes.FakeProjectRepository();
            Assert.AreEqual<int>(10, repository.RetrieveProjects().Count());
        }

        [TestMethod]
        public void Project_Repository_RetrieveProjects_Return_Not_Null() {
            DataAccess.IProjectsRepository repository = new Fakes.FakeProjectRepository();            
            Assert.IsNotNull(repository.RetrieveProjects());
        }

        [TestMethod]
        public void Project_Repository_Return_One_With_Known_Id() {
           FakeProjectRepository repository = new Fakes.FakeProjectRepository();
           Assert.AreEqual<int>(1, repository.RetrieveProjects().WithProjectId(repository.KnowProductId).Count());
        }

        [TestMethod]
        public void ProjectService_Return_1_Project_With_Know_Id() {
            FakeProjectRepository fakeRep = new FakeProjectRepository();
            ProjectsService service = new ProjectsService(fakeRep);

            Project p = service.RetrieveProject(fakeRep.KnowProductId);

            Assert.IsNotNull(p);
        }

        #region Projects

        [TestMethod]
        public void ProjectId_Throw_ArgumentException_When_Empty_Guid() {
            try {
                ProjectId pid = new ProjectId(Guid.Empty, "");
            }
            catch (ArgumentException) {
                return;
            }

            Assert.Fail();
        }

        [TestMethod]
        public void ProjectId_Throw_ArgumentException_When_Empty_Or_Null_Name_PArameter() {
            try {
                ProjectId pid = new ProjectId(Guid.NewGuid(), string.Empty);
                pid = new ProjectId(Guid.NewGuid(), null);
            }
            catch (ArgumentException) {
                return;
            }

            Assert.Fail();
        }

        [TestMethod]
        public void Project_Must_Have_Id() {

            Guid pid = Guid.NewGuid();
           
            Project project = new Project(pid, "product");

            Assert.IsNotNull(project.ProjectId);
            Assert.AreEqual<Guid>(pid, project.ProjectId.Id);
            Assert.AreEqual<string>("product", project.ProjectId.Name);
        }

        #endregion
    }
}
